﻿using System;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.NetworkInformation;
using System.Net;
using System.IO;

namespace oPing
{
    public partial class Form1 : Form
    {        
        //private uint pingsSent;
        AutoResetEvent resetEvent = new AutoResetEvent(false);
        //private bool btStopClicked = false;
        string saveFile = "";
        System.Windows.Forms.Timer sleepTimer = new System.Windows.Forms.Timer();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.ActiveControl = txtIP;
            sleepTimer.Interval = 1000;
            sleepTimer.Enabled = false;
        }        

        private void btnStart_Click(object sender, EventArgs e)
        {
            //pingsSent = 0;
            txtResponse.Clear();
            //btStopClicked = false;

            IPAddress[] address = new IPAddress[1];
            try
            {
                address = Dns.GetHostAddresses(txtIP.Text);
                btnStop.Enabled = true;
                btnStart.Enabled = false;
            }
            catch (Exception)
            {
                MessageBox.Show("Geben Sie eine gültige Adresse ein");
                this.ActiveControl = txtIP;
                txtIP.SelectAll();
                return;
            }

            txtResponse.AppendText("Pinging: " + txtIP.Text + " [" + address[0].ToString() +"] with 32 bytes of data:\r\n\r\n");
            WriteFile("Pinging: " + txtIP.Text + " [" + address[0].ToString() + "] with 32 bytes of data:\r\n");

            //SendPing();      
            sleepTimer.Start();
            sleepTimer.Tick += sleepTimer_Tick;
        }

        void sleepTimer_Tick(object sender, EventArgs e)
        {
            SendPing();
        }

        private void SendPing()
        {
            Ping pingSender = new Ping();

            pingSender.PingCompleted += pingSender_PingCompleted;

            byte[] buffer = Encoding.ASCII.GetBytes("oooooooooooooooooooooooooooooooo");

            PingOptions packetOptions = new PingOptions(128, false);
            
            pingSender.SendAsync(txtIP.Text, 2000, buffer, packetOptions, resetEvent);
                                    
        }

        void pingSender_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                txtResponse.AppendText("Ping was canceled..\r\n");
                ((AutoResetEvent)e.UserState).Set();
            }
            else if (e.Error != null)
            {
                txtResponse.AppendText("An error occured: " + e.Error + "\r\n");
                ((AutoResetEvent)e.UserState).Set();
            }
            else
            {
                PingReply pingResponse = e.Reply;
                ShowPingResults(pingResponse);
            }
                        
            ((IDisposable)sender).Dispose();          
        }

        private void ShowPingResults(PingReply pingResponse)
        {
            if (pingResponse == null)
            {
                txtResponse.AppendText("There was no response.\r\n\r\n");
                return;
            }
            else if (pingResponse.Status == IPStatus.Success)
            {
                //txtResponse.Text += "Reply from: " + pingResponse.Address.ToString() + ": Bytes=" + pingResponse.Buffer.Length + " Time=" + pingResponse.RoundtripTime + "ms TTL=" + pingResponse.Options.Ttl + " | Time: " + DateTime.Now + "\r\n";
                txtResponse.AppendText("Reply from: " + pingResponse.Address.ToString() + ": Bytes=" + pingResponse.Buffer.Length + " Time=" + pingResponse.RoundtripTime + "ms TTL=" + pingResponse.Options.Ttl + " | Time: " + DateTime.Now + "\r\n");
                WriteFile("Reply from: " + pingResponse.Address.ToString() + ": Bytes=" + pingResponse.Buffer.Length + " Time=" + pingResponse.RoundtripTime + "ms TTL=" + pingResponse.Options.Ttl + " | Time: " + DateTime.Now);
            }
            else if (pingResponse.Status.ToString() == "TimedOut")
            {
                txtResponse.AppendText("Ping timed out. | Time: " + DateTime.Now + "\r\n");
                WriteFile("Ping timed out. | Time: " + DateTime.Now);
            }
            else
            {
                txtResponse.AppendText("Ping was unsuccesful: " + pingResponse.Status + " | Time: " + DateTime.Now + "\r\n");
                WriteFile("Ping was unsuccesful: " + pingResponse.Status + " | Time: " + DateTime.Now);
            }
            
            //pingsSent++;         
            
            //if (pingsSent < 10 && btStopClicked == false)
            //if (btStopClicked == false)
            //{
            //    Thread.Sleep(1000);
            //    resetEvent.WaitOne(1000);
            //    SendPing();
            //}
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult diaResult = MessageBox.Show("Do you want to quit this application?", "Quit Application", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1);
            if (diaResult == DialogResult.No)
            {
                e.Cancel = true;
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            //btStopClicked = true;
            btnStop.Enabled = false;
            btnStart.Enabled = true;
            
            this.ActiveControl = txtIP;
            txtIP.SelectAll();

            sleepTimer.Stop();
            sleepTimer.Dispose();
            sleepTimer.Tick -= sleepTimer_Tick;
            
        }

        private void cbSave_CheckedChanged(object sender, EventArgs e)
        {
            if (cbSave.Checked)
            {                
                SaveFileDialog sfdSaved = new SaveFileDialog();
                sfdSaved.FileName = "oPing";
                sfdSaved.Filter = "Text Files (*.txt)|*.txt";                
                if (sfdSaved.ShowDialog() == DialogResult.OK)
                {
                    if (File.Exists(sfdSaved.FileName))
                    {
                        try
                        {
                            File.Delete(sfdSaved.FileName);
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("Error on overriding the file.");
                            return;
                        }
                    }
                    saveFile = sfdSaved.FileName;                          
                }
                else
                {
                    cbSave.Checked = false;                    
                }
            }
        }

        private void WriteFile(string input)
        {
            if (saveFile != "" && cbSave.Checked == true)
            {
                using (StreamWriter sw = File.AppendText(saveFile))
                {
                    sw.WriteLine(input);
                }
            }
        }

        private void txtIP_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnStart_Click(this, EventArgs.Empty);
            }
        }
    }
}